import { ConfigService } from 'my-web-core/config';
import React, { useEffect, useState } from 'react';
import { BrowserRouter, Route, Routes } from 'react-router-dom';

import App from '@/App';
import getAuthenticationRoute from '@/features/authentication/Router';
import getHomeRoute from '@/features/home/Router';
import getUserRoute from '@/features/users/Router';
import LocalGeneralConfig from '@/shared/models/local-general-config';
import Hook from '@/shared/redux/hook';

function AppRouter() {
  const currentUser = Hook.useAppSelector((state) => state.authentication.currentUser);
  const [basename, setBasename] = useState<string>();

  const NotFound = React.lazy(() => import('@/shared/components/NotFound'));

  useEffect(() => {
    ConfigService.getLocalGeneralConfig(new LocalGeneralConfig()).then((res) =>
      setBasename(res.routeBasename),
    );
  }, []);

  /**
   * IMPORTANT!!!
   * [setBasename(res.routeBasename)] would not make [<BrowserRouter basename={basename} >] work even includes [key] property.
   * That's why we have to make sure [basename] value is ready before we return [<BrowserRouter basename={basename} >].
   *
   * We also cannot use process.env.PUBLIC_URL because we cannot change it after build.
   */
  return basename ? (
    <BrowserRouter basename={basename}>
      <Routes>
        <Route path="/" element={<App />}>
          {getAuthenticationRoute(currentUser)}
          {getHomeRoute(currentUser)}
          {getUserRoute(currentUser)}
          <Route path="*" element={<NotFound />} />
        </Route>
      </Routes>
    </BrowserRouter>
  ) : (
    <></>
  );
}

export default AppRouter;
